package cn.dengta.webapp.user.entity.game;

import java.util.*;

import cn.dengta.webapp.base.entity.TimeBasedEntity;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.codeplayer.util.Cmp;

/** 骰子游戏 */
@Setter
@Getter
@Accessors(chain = true)
@TableName("dt_game_dice_log")
public class GameDiceLog extends TimeBasedEntity {

	/** 骰子 */
	public static final int dict_type = 1;
	/** 转盘 */
	public static final int roulette_type = 2;

	/** 用户id */
	private Long userId;
	/** 游戏id */
	private Long gameId;
	/** 1=骰子；2=转盘；默认为1 */
	private Integer type;
	/** 游戏记录id */
	private Long logId;
	/** 下注的金币数 */
	private Integer golds;
	/** 得到金币数 */
	private Integer received;
	/** 状态 -9=已关闭；0=初始化；1=正在下注；2=下注完成；9=已开奖 */
	private Integer status;
	/** 开奖数据，如：[1,2,3] */
	private String result;
	/** 开始下注时间 */
	private Date beginBetTime;
	/** 结束下注时间 */
	private Date endBetTime;
	/** 开奖时间 */
	private Date lotteryTime;
	/** 开奖数据 */
	private transient List<Integer> res;
	/** 是否 大 */
	public transient boolean hasBig;
	/** 是否小 */
	public transient boolean hasSmall;
	/** 是否单 */
	public transient boolean hasSingle;
	/** 是否双 */
	public transient boolean hasDouble;
	/** 是否豹子 */
	public transient boolean hasLeopard;
	/** 是否红色 */
	public transient boolean hasRed;
	/** 是否黑色 */
	public transient boolean hasBlack;
	/** 是否0 */
	public transient boolean hasZero;
	/** 是否1-12 */
	public transient boolean hasTwelve;
	/** 是否13-24 */
	public transient boolean hasTwentyFour;
	/** 是否25-36 */
	public transient boolean hasThirtySix;

	public static final String STATUS = "status";

	/** 转盘 */
	public static Map<Integer, GameDiceLog.Roulette> roulette = new HashMap<>(64);

	static {
		roulette.put(0, new GameDiceLog.Roulette(0, GameDiceLog.Roulette.green));
		roulette.put(1, new GameDiceLog.Roulette(1, GameDiceLog.Roulette.red));
		roulette.put(2, new GameDiceLog.Roulette(2, GameDiceLog.Roulette.black));
		roulette.put(3, new GameDiceLog.Roulette(3, GameDiceLog.Roulette.red));
		roulette.put(4, new GameDiceLog.Roulette(4, GameDiceLog.Roulette.black));
		roulette.put(5, new GameDiceLog.Roulette(5, GameDiceLog.Roulette.red));
		roulette.put(6, new GameDiceLog.Roulette(6, GameDiceLog.Roulette.black));
		roulette.put(7, new GameDiceLog.Roulette(7, GameDiceLog.Roulette.red));
		roulette.put(8, new GameDiceLog.Roulette(8, GameDiceLog.Roulette.black));
		roulette.put(9, new GameDiceLog.Roulette(9, GameDiceLog.Roulette.red));
		roulette.put(10, new GameDiceLog.Roulette(10, GameDiceLog.Roulette.black));
		roulette.put(11, new GameDiceLog.Roulette(11, GameDiceLog.Roulette.black));
		roulette.put(12, new GameDiceLog.Roulette(12, GameDiceLog.Roulette.red));
		roulette.put(13, new GameDiceLog.Roulette(13, GameDiceLog.Roulette.black));
		roulette.put(14, new GameDiceLog.Roulette(14, GameDiceLog.Roulette.red));
		roulette.put(15, new GameDiceLog.Roulette(15, GameDiceLog.Roulette.black));
		roulette.put(16, new GameDiceLog.Roulette(16, GameDiceLog.Roulette.red));
		roulette.put(17, new GameDiceLog.Roulette(17, GameDiceLog.Roulette.black));
		roulette.put(18, new GameDiceLog.Roulette(18, GameDiceLog.Roulette.red));
		roulette.put(19, new GameDiceLog.Roulette(19, GameDiceLog.Roulette.red));
		roulette.put(20, new GameDiceLog.Roulette(20, GameDiceLog.Roulette.black));
		roulette.put(21, new GameDiceLog.Roulette(21, GameDiceLog.Roulette.red));
		roulette.put(22, new GameDiceLog.Roulette(22, GameDiceLog.Roulette.black));
		roulette.put(23, new GameDiceLog.Roulette(23, GameDiceLog.Roulette.red));
		roulette.put(24, new GameDiceLog.Roulette(24, GameDiceLog.Roulette.black));
		roulette.put(25, new GameDiceLog.Roulette(25, GameDiceLog.Roulette.red));
		roulette.put(26, new GameDiceLog.Roulette(26, GameDiceLog.Roulette.black));
		roulette.put(27, new GameDiceLog.Roulette(27, GameDiceLog.Roulette.red));
		roulette.put(28, new GameDiceLog.Roulette(28, GameDiceLog.Roulette.black));
		roulette.put(29, new GameDiceLog.Roulette(29, GameDiceLog.Roulette.black));
		roulette.put(30, new GameDiceLog.Roulette(30, GameDiceLog.Roulette.red));
		roulette.put(31, new GameDiceLog.Roulette(31, GameDiceLog.Roulette.black));
		roulette.put(32, new GameDiceLog.Roulette(32, GameDiceLog.Roulette.red));
		roulette.put(33, new GameDiceLog.Roulette(33, GameDiceLog.Roulette.black));
		roulette.put(34, new GameDiceLog.Roulette(34, GameDiceLog.Roulette.red));
		roulette.put(35, new GameDiceLog.Roulette(35, GameDiceLog.Roulette.black));
		roulette.put(36, new GameDiceLog.Roulette(36, GameDiceLog.Roulette.red));
	}

	public static GameDiceLog init(Long userId, Long gameId) {
		GameDiceLog log = new GameDiceLog();
		log.setUserId(userId);
		log.setGameId(gameId);
		return log;
	}

	/** 判断是否 已超出下注时间 */
	public boolean canBetTime() {
		if (beginBetTime != null && endBetTime != null) {
			long millis = System.currentTimeMillis();
			return millis > endBetTime.getTime();
		}
		return false;
	}

	/** 是否可开奖 */
	public boolean canLottery() {
		return Cmp.lt(this.status, 9);
	}

	public boolean hasBig() {
		return hasBig;
	}

	public boolean hasSmall() {
		return hasSmall;
	}

	public boolean hasSingle() {
		return hasSingle;
	}

	public boolean hasDouble() {
		return hasDouble;
	}

	public boolean hasLeopard() {
		return hasLeopard;
	}

	public void setResult(String result) {
		this.result = result;
		res = JSONArray.parseArray(result, Integer.class);
		/** 骰子结果 */
		if (Cmp.eq(this.type, dict_type)) {
			int sum = res.get(0) + res.get(1) + res.get(2);
			hasLeopard = res.get(0) == res.get(1) && res.get(1) == res.get(2);
			hasBig = !hasLeopard && sum >= 11;
			hasSmall = !hasLeopard && !hasBig;
			hasDouble = !hasLeopard && sum % 2 == 0;
			hasSingle = !hasLeopard && !hasDouble;
			return;
		}
		/** 转盘结果 */
		if (Cmp.eq(this.type, roulette_type)) {
			int re = res.get(0);
			Roulette rou = roulette.get(re);
			hasZero = rou.hasZero();
			hasRed = rou.hasRed();
			hasBlack = rou.hasBlack();
			hasTwelve = re >= 1 && re <= 12;
			hasTwentyFour = re >= 13 && re <= 24;
			hasThirtySix = re >= 25 && re <= 36;
			hasDouble = re % 2 == 0;
			hasSingle = !hasDouble;
		}
	}

	public Map<String, Boolean> toDiceMap() {
		Map<String, Boolean> map = new HashMap<>();
		if (Cmp.eq(this.type, dict_type)) {
			map.put("hasBig", hasBig);
			map.put("hasSmall", hasSmall);
			map.put("hasSingle", hasSingle);
			map.put("hasDouble", hasDouble);
			map.put("hasLeopard", hasLeopard);
		}
		if (Cmp.eq(this.type, roulette_type)) {
			map.put("hasSingle", hasSingle);
			map.put("hasDouble", hasDouble);
			map.put("hasZero", hasZero);
			map.put("hasRed", hasRed);
			map.put("hasBlack", hasBlack);
			map.put("hasTwelve", hasTwelve);
			map.put("hasTwentyFour", hasTwentyFour);
			map.put("hasThirtySix", hasThirtySix);
		}
		return map;
	}

	@Getter
	@Setter
	public static class Roulette {

		/** 绿色 */
		public static final String green = "green";
		/** 红色 */
		public static final String red = "red";
		/** 黑色 */
		public static final String black = "black";

		/** 编号：0-36 */
		private Integer code;
		/** 颜色 */
		private String color;

		public Roulette(Integer code, String color) {
			this.code = code;
			this.color = color;
		}

		/** 是否红色 */
		public boolean hasRed() {
			return red.equals(this.color);
		}

		/** 是否黑色 */
		public boolean hasBlack() {
			return black.equals(this.color);
		}

		/** 是否绿色 */
		public boolean hasGreen() {
			return green.equals(this.color);
		}

		/** 是否0 */
		public boolean hasZero() {
			return Cmp.eq(this.code, 0);
		}

	}

}
